/**
 * 文件名：DiagnosticVFS.java
 *
 * 创建人：Elvin Zhao - 279152260@qq.com
 *
 * 创建时间：2025年6月24日 上午12:54:49
 *
 * 版权所有：FNII
 */
package com.jeeplus.common;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.ibatis.io.VFS;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

public class DiagnosticVFS extends VFS {

	private static final Set<String> INVALID_PATHS = Collections.synchronizedSet(new HashSet<>());

	private static final Set<String> VALID_PATHS = Collections.synchronizedSet(new HashSet<>());

	private static final String REPORT_FILE = "vfs_scan_report.txt";

	@Override
	public List<String> list(String path) throws IOException {
		List<String> resources = new ArrayList<>();
		PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

		try {
			Resource[] resourceArray = resolver.getResources("classpath*:" + path + "/**");
			for (Resource resource : resourceArray) {
				String urlPath = getFullPath(resource);

				if (isValidPath(urlPath)) {
					VALID_PATHS.add(urlPath);
					resources.add(urlPath);
				} else {
					INVALID_PATHS.add(urlPath);
					logInvalidPath(urlPath);
				}
			}
		} finally {
			// 扫描完成后生成报告
			if (!INVALID_PATHS.isEmpty()) {
				generateDiagnosticReport();
			}
		}

		return resources;
	}

	private String getFullPath(Resource resource) {
		try {
			URL url = resource.getURL();
			String protocol = url.getProtocol();

			if ("jar".equals(protocol)) {
				String fullPath = URLDecoder.decode(url.toString(), "UTF-8");
				return fullPath.substring(fullPath.indexOf("!/") + 2);
			} else if ("file".equals(protocol)) {
				return URLDecoder.decode(url.getPath(), "UTF-8");
			}
			return resource.getURL().toString();
		} catch (IOException e) {
			return resource.getDescription();
		}
	}

	private boolean isValidPath(String path) {
		// 基础检查：空路径
		if (path == null || path.isEmpty())
			return false;

		try {
			// 编码有效性检查
			byte[] bytes = path.getBytes("UTF-8");
			String decoded = new String(bytes, "UTF-8");

			// 非ASCII字符检查
			for (char c : path.toCharArray()) {
				if (c > 0x7F) {
					return false;
				}
			}

			// 特殊字符检查
			return !path.matches(".*[\\x00-\\x1F\\x7F\\\\:*?\"<>|].*");
		} catch (UnsupportedEncodingException e) {
			return false;
		}
	}

	private void logInvalidPath(String invalidPath) {

		// 十六进制转储
		StringBuilder hexDump = new StringBuilder("HEX: ");
		for (byte b : invalidPath.getBytes()) {
			hexDump.append(String.format("%02X ", b));
		}

		// 字符级分析
		for (int i = 0; i < invalidPath.length(); i++) {
			char c = invalidPath.charAt(i);
			System.err.printf("位置 %d: U+%04X %s - %s%n", i, (int) c, Character.getName(c),
					c > 0x7F ? "非ASCII" : "ASCII");
		}
	}

	private void generateDiagnosticReport() {
		try (java.io.PrintWriter out = new java.io.PrintWriter(REPORT_FILE)) {
			out.println("================== VFS 扫描诊断报告 ==================");
			out.println("扫描时间: " + new Date());
			out.println("\n>>> 发现 " + INVALID_PATHS.size() + " 个非法路径 <<<\n");

			// 非法路径详情
			out.println("非法路径列表:");
			for (String path : INVALID_PATHS) {
				out.println("\n--------------------------------------------------");
				out.println("原始路径: " + path);

				// 十六进制表示
				out.print("HEX: ");
				for (byte b : path.getBytes()) {
					out.printf("%02X ", b);
				}
				out.println();

				// Unicode 转义序列
				out.print("Unicode: ");
				path.chars().forEach(c -> out.printf("\\u%04X ", c));
				out.println();

				// 字符分析
				out.println("字符分解:");
				for (int i = 0; i < path.length(); i++) {
					char c = path.charAt(i);
					out.printf("  %3d: %c | U+%04X | %s | %s%n", i, Character.isISOControl(c) ? '?' : c, (int) c,
							Character.getName(c), c > 0x7F ? "非ASCII" : "ASCII");
				}
			}

			// 环境信息
			out.println("\n环境诊断:");
			out.println("文件系统编码: " + System.getProperty("file.encoding"));
			out.println("JVM 默认编码: " + java.nio.charset.Charset.defaultCharset());
			out.println("操作系统: " + System.getProperty("os.name"));
			out.println("Java 版本: " + System.getProperty("java.version"));

			// 编码建议
			out.println("\n修复建议:");
			out.println("1. 在启动脚本中添加: -Dfile.encoding=UTF-8");
			out.println("2. 在 Maven 中配置: <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>");
			out.println("3. 检查以下文件是否包含中文/特殊字符:");
			out.println("   " + INVALID_PATHS.stream().limit(5).collect(Collectors.joining("\n   ")));

			out.println("\n报告已保存至: " + new java.io.File(REPORT_FILE).getAbsolutePath());
		} catch (IOException e) {
		}
	}

	// 其他必要方法实现
	@Override
	public boolean isValid() {
		return true;
	}

	@Override
	protected List<String> list(URL url, String path) throws IOException {
		return Collections.emptyList();
	}
}